package org.ysling.litemall.core.tasks.service;
/**
 *  Copyright (c) [ysling] [927069313@qq.com]
 *  [litemall-plus] is licensed under Mulan PSL v2.
 *  You can use this software according to the terms and conditions of the Mulan PSL v2.
 *  You may obtain a copy of Mulan PSL v2 at:
 *              http://license.coscl.org.cn/MulanPSL2
 *  THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 *  EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 *  MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 *  See the Mulan PSL v2 for more details.
 */

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.ysling.litemall.core.service.ActionLogService;
import javax.annotation.PostConstruct;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 定时任务执行服务类
 * @author Ysling
 */
@Slf4j
@Component
public class TaskService {

    @Autowired
    private ActionLogService logService;

    private final RDelayedQueue<TaskRunnable> delayedQueue;

    private final RBlockingQueue<TaskRunnable> blockingQueue;

    public TaskService(@Qualifier("redisson") RedissonClient redissonClient){
        this.blockingQueue = redissonClient.getBlockingQueue("TASK-SERVICE");
        this.delayedQueue = redissonClient.getDelayedQueue(blockingQueue);
    }

    @PostConstruct
    @SuppressWarnings("InfiniteLoopStatement")
    private void init() {
        CompletableFuture.runAsync(() -> {
            while (true) {
                try {
                    // 获取队列
                    TaskRunnable task = blockingQueue.take();
                    // 队列运行
                    task.run();
                } catch (Exception e) {
                    e.printStackTrace();
                    //记录异常操作
                    logService.logOrderFail("系统处理延时任务", e.getMessage());
                }
            }
        });
    }

    public void addTask(TaskRunnable task){
        for (TaskRunnable runnable :delayedQueue) {
            if (runnable.equals(task)){
                return;
            }
        }
        delayedQueue.offer(task, task.getSeconds(), TimeUnit.MILLISECONDS);
    }

    public void removeTask(TaskRunnable task){
        if (!delayedQueue.removeIf(runnable -> runnable.equals(task))){
            log.error(String.format("removeTask失败--{%s}",task.getId()));
        }
    }

}
